<template>
    <div class="content-wrapper-view">
        <div class="content-wrapper-body">
            <div class="filter-wrapper">
                <el-form ref="filterForm" :model="listQuery" :inline="true">
                    <el-form-item prop="roleName" size="medium">
                        <el-input v-model="listQuery.roleName" placeholder="关键字"></el-input>
                    </el-form-item>

                    <el-button type="primary" size="medium" icon="el-icon-search" @click="handleFilter">搜索</el-button>
                    <el-button type="primary" size="medium" icon="el-icon-mars-reset" @click="handleResetFilter">重置
                    </el-button>
                    <el-button :disabled="!authorize('upms:role:add')" type="primary" size="medium" icon="el-icon-plus" @click="handleCreate">添加</el-button>
                    <el-button :disabled="!authorize('upms:role:delete')" type="danger" size="medium" icon="el-icon-delete" @click="handleDelete">批量删除</el-button>
                </el-form>
            </div>

            <el-table
                    :data="list"
                    border fit
                    highlight-current-row
                    v-loading="listLoading"
                    element-loading-text="给我一点时间"
                    empty-text="-"
                    @selection-change="handleSelectionChange">

                <el-table-column type="selection" width="55" align="center"></el-table-column>
                <el-table-column type="index" width="55" align="center"></el-table-column>

                <el-table-column label="名称" align="center">
                    <template slot-scope="scope"> {{ scope.row.roleName }}</template>
                </el-table-column>
                <el-table-column label="编码" align="center">
                    <template slot-scope="scope"> {{ scope.row.roleCode }}</template>
                </el-table-column>
                <el-table-column label="备注" align="center">
                    <template slot-scope="scope"> {{ scope.row.roleDesc }}</template>
                </el-table-column>
                <el-table-column label="创建时间" align="center">
                    <template slot-scope="scope"> {{ scope.row.ctime | parseTime('{y}-{m}-{d} {h}:{i}')}}</template>
                </el-table-column>
                <el-table-column label="最后更新时间" align="center">
                    <template slot-scope="scope"> {{ scope.row.utime | parseTime('{y}-{m}-{d} {h}:{i}') }}</template>
                </el-table-column>

                <el-table-column label="操作" width="250" align="center">
                    <template slot-scope="scope">
                        <el-button :disabled="!authorize('upms:role:addPermission', scope)" size="small" type="primary" icon="edit" @click="handleAuthorize(scope.row)">分配权限</el-button>
                        <el-button :disabled="!authorize('upms:role:update', scope)" size="small" type="primary" icon="edit" @click="handleUpdate(scope.row)">编辑</el-button>
                        <el-button :disabled="!authorize('upms:role:delete', scope)" size="small" type="danger" icon="delete" @click="handleDelete(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>

            <div v-if="!listLoading" class="pagination-container">
                <el-pagination
                        background
                        @size-change="handleSizeChange"
                        @current-change="handleCurrentChange"
                        :current-page="listQuery.page"
                        :page-sizes="[10, 20, 30, 50]"
                        :page-size="listQuery.limit"
                        layout="total, sizes, prev, pager, next, jumper"
                        :total="total">
                </el-pagination>
            </div>

            <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" @close="handleDialogClose">
                <el-form ref="form" :model="form" :rules="rules" label-width="120px">

                    <el-form-item label="名称" prop="roleName">
                        <el-input v-model="form.roleName" placeholder="名称" style="width: 80%;"></el-input>
                    </el-form-item>
                    <el-form-item label="编码" prop="roleCode">
                        <el-input v-model="form.roleCode" placeholder="编码" style="width: 80%;"></el-input>
                    </el-form-item>
                    <el-form-item label="备注" prop="roleDesc">
                        <el-input v-model="form.roleDesc" placeholder="备注" style="width: 80%;"></el-input>
                    </el-form-item>

                </el-form>

                <div slot="footer" class="dialog-footer">
                    <el-button @click="cancel('form')">取 消</el-button>
                    <el-button v-if="dialogStatus == 'create'" type="primary" @click="create('form')">确 定</el-button>
                    <el-button v-else type="primary" @click="update('form')">确 定</el-button>
                </div>
            </el-dialog>

            <el-dialog title="分配权限" :visible.sync="dialogFormVisibleAuthorize" @close="handleDialogCloseAuthorize">
                <div class="permissionDialog" v-loading="savePermissionLoading">

                    <el-tree :data="tree" node-key="id" ref="tree"
                             v-loading="loadingTree"
                             highlight-current
                             default-expand-all
                             show-checkbox
                             :expand-on-click-node="false"
                             :props="defaultProps"
                             @check="handleNodeCheckChange">
                            <span class="custom-tree-node" slot-scope="{ node, data }">
                                <span class="node-label">{{ node.label }}</span>
                                <span class="node-permission">

                                    <el-checkbox-group v-model="permissionCheckList">
                                        <el-checkbox :label="'checkAll-'+node.data.id" @change="handleCheckAll" v-if="getMenuNodePermission(node.data.id).length > 0">全选</el-checkbox>
                                        <template v-for="item in getMenuNodePermission(node.data.id)">
                                            <el-checkbox :label="node.data.id+'-'+item.id" :key="node.data.id+'-'+item.id">{{item.name}}</el-checkbox>
                                        </template>
                                    </el-checkbox-group>

                                </span>
                            </span>

                    </el-tree>

                </div>

                <div slot="footer" class="dialog-footer">
                    <el-button type="primary" @click="authorizeAction" :disabled="savePermissionLoading">{{savePermissionLoading ? "保存中" : "确 定"}}</el-button>
                </div>
            </el-dialog>
        </div>




    </div>
</template>

<script>
    import { created, updated, deleted, selectOne, selectList, selectPage } from '@/api/system/role'
    import { selectTree } from '@/api/system/menu'
    import { ResultMessage } from '@/libs/response'
    import {
        selectList as selectListPermission,
        findPermissionByMenuId,
        generateDefaultPermission
    } from '@/api/system/permission'
    import {
        cudRolePermission,
        selectList as selectListRolePermission
    } from '@/api/system/role_permission'
    import valid from '@/libs/rules'
    import { isAuth } from "@/libs/auth";

    export default {
        name: 'Role',
        data() {
            let required = valid.required()
            return {
                list: null,
                total: null,
                listLoading: true,
                listQuery: {
                    page: 1,
                    limit: 10
                },
                form: {
                    sex: 1,
                    status: true
                },
                rules: {
                    roleName: [required]
                },
                multipleSelection: [],
                dialogFormVisible: false,
                dialogStatus: '',
                textMap: {update: '编辑', create: '创建'},

                tree: null,
                loadingTree: false,
                dialogFormVisibleAuthorize: false,
                defaultProps: {
                    label: 'name',
                    children: 'children'
                },
                permissionList: [],
                permissionCheckList: [],
                roleId: null,
                savePermissionLoading: false

            }
        },
        created() {
            this.getPage()
        },
        methods: {
            authorize(auth, rows) {
                //按钮权限验证
                return isAuth(auth)
            },
            handleCheckAll(check, e) { //全选或不选
                const val = e.target.getAttribute('value').split("-")
                const menuId = val[1]

                //获取当前选中菜单的权限
                let nodePermissions = this.getMenuNodePermission(menuId)

                if(check) {
                    this.$refs.tree.setChecked(menuId, true)
                    let permissions = []
                    for (let item of nodePermissions) {
                        permissions.push(item.menuId+'-'+item.id)
                    }
                    //将选中的去重
                    this.permissionCheckList = Array.from(new Set([...this.permissionCheckList, ...permissions]))
                } else {
                    this.$refs.tree.setChecked(menuId, false)
                    let tempPermission = []
                    for (let item of nodePermissions) {
                        tempPermission.push(item.menuId+'-'+item.id)
                    }
                    for (let item of tempPermission) {
                        //获取索引
                        let index = this.permissionCheckList.findIndex(function (val) {
                            return val == item
                        })
                        if (index != -1) {
                            //删除元素
                            this.permissionCheckList.splice(index, 1)
                        }
                    }
                }

            },
            handleNodeCheckChange(data, check) {

            },
            handleDialogCloseAuthorize() {
                this.tree = []
                this.permissionList = []
                this.permissionCheckList = []
                this.roleId = null
            },
            handleAuthorize(row) {
                this.dialogFormVisibleAuthorize = true
                this.getAllPermission()
                this.roleId = row.id
            },
            authorizeAction() {//提交角色权限
                if(this.roleId) {
                    this.savePermissionLoading = true

                    //删除checkAll复选框然后在提交数据
                    for(let ckIndex of this.$refs.tree.getCheckedKeys()) {
                        //获取checkAll复选框的索引
                        let index = this.permissionCheckList.findIndex(function (value, index, arr) {
                            const split = value.split('-')
                            return split[0] === 'checkAll'
                        })
                        if(index != -1) {
                            this.permissionCheckList.splice(index, 1)
                        }
                    }

                    let data = {"roleId": this.roleId, "permissions": this.permissionCheckList}
                    cudRolePermission(data).then(response => {
                        if (response.data.status === 200) {
                            this.$notify({
                                title: '提示', message: '操作成功',
                                type: 'success', duration: 2000
                            })
                            this.handleResetFilter()
                        } else if (response.data.status === 601) {
                            this.$notify({
                                title: '提示', message: response.data.msg,
                                type: 'warning', duration: 2000
                            })
                        } else {
                            this.$notify({
                                title: '操作失败', message: response.data.msg,
                                type: 'error', duration: 2000
                            })
                        }
                        this.dialogFormVisibleAuthorize = false
                        this.savePermissionLoading = false
                    }).catch(error => {
                        this.savePermissionLoading = false
                    })
                }
            },
            getRolePermission(roleId) {//获取角色对应的权限
                selectListRolePermission({"roleId": roleId}).then(response => {
                    if (response.data.status === 200) {

                        const s = new Set()
                        let menuIds = [], permissionIds = []

                        for(let item of response.data.data) {
                            s.add(item.menuId)
                            permissionIds.push(item.menuId + '-' + item.permissionId)
                        }

                        setTimeout(() => {
                            menuIds = Array.from(s)
                            for(let m of menuIds) {
                                //选中菜单
                                this.$refs.tree.setChecked(m, true)
                            }

                            //选中的权限
                            this.permissionCheckList = permissionIds
                        }, 200)


                    } else if (response.data.status === 601) {
                        this.$notify({
                            title: '提示', message: response.data.msg,
                            type: 'warning', duration: 2000
                        })
                    } else {
                        this.$notify({
                            title: '发生错误', message: response.data.msg,
                            type: 'error', duration: 2000
                        })
                    }
                    this.loadingTree = false
                })
            },
            getTree() {//获取菜单树
                selectTree().then(response => {
                    this.tree = response.data.data
                    this.treeDialog = response.data.data
                    this.loadingTree = false
                }).then(() => {
                    this.getRolePermission(this.roleId)
                })
            },
            getAllPermission() { //加载所有权限
                this.loadingTree = true
                selectListPermission().then(response => {
                    if (response.data.status === 200) {
                        this.permissionList = response.data.data
                    } else {
                        this.$notify({
                            title: '发生错误', message: response.data.msg,
                            type: 'error', duration: 2000
                        })
                    }
                }).then(() => {
                    this.getTree()
                }).catch(error => {
                })
            },
            getMenuNodePermission(menuId) { //根据菜单ID从所有权限中获取对应的权限
                let nodePermission = this.permissionList.filter(function (item, index, array) {
                    return item.menuId == menuId
                })
                return nodePermission
            },

            handleFilter() {//条件过滤
                this.listQuery.page = 1
                this.getPage()
            },
            handleResetFilter() {//重置过滤条件
                this.cancel('filterForm')
                this.getPage()
            },
            handleDialogClose() {//关闭窗口回调函数
                this.cancel('form')
            },
            handleSelectionChange(val) {//多选
                this.multipleSelection = val;
            },
            handleSizeChange(val) {
                this.listQuery.page = 1
                this.listQuery.limit = val
                this.getPage()
            },
            handleCurrentChange(val) {
                this.listQuery.page = val
                this.getPage()
            },
            handleCreate() {//添加数据窗口
                this.dialogStatus = 'create'
                this.dialogFormVisible = true
            },
            handleUpdate(row) {//修改数据窗口
                this.getData(row.id).then(response => {
                    if(response) {
                        this.dialogStatus = 'update'
                        this.dialogFormVisible = true
                        this.form = Object.assign({}, response.data.data)
                    }
                })
            },
            handleDelete(row) {//批量删除数据
                let ids = []
                if (row.id != undefined) {
                    ids.push(row.id)
                } else {
                    if (this.multipleSelection.length > 0) {
                        for (let item of this.multipleSelection) {
                            ids.push(item.id)
                        }
                    }
                }
                if (ids.length <= 0) {
                    this.$notify({
                        title: '提示', message: '请选择需要删除的记录',
                        type: 'warning', duration: 2000
                    })
                } else {
                    this.$confirm('确定要删除？', '提示', {
                        confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'
                    }).then(() => {
                        deleted({idList: ids}).then(response => {
                            if(ResultMessage(response)) {
                                this.getPage()
                            }
                        }).catch(error => {
                            this.$notify({
                                title: '提示', message: '删除失败',
                                type: 'error', duration: 2000
                            })
                        })
                    }).catch(() => {
                    })
                }
            },
            getData(id) { //根据ID查询数据
                this.listLoading = true
                return selectOne(id).then(response => {
                    if(ResultMessage(response, false)) {
                        this.listLoading = false
                        return response
                    } else {
                        this.listLoading = false
                        return null
                    }

                }).catch(error => {
                    this.$notify({
                        title: '提示', message: '根据ID获取数据失败',
                        type: 'error', duration: 2000
                    })
                    this.listLoading = false
                })
            },
            getPage() {//查询分页列表
                this.listLoading = true
                selectPage(this.listQuery).then(response => {
                    if(ResultMessage(response, false)) {
                        this.list = response.data.data.list
                        this.total = parseInt(response.data.data.total)
                        this.listLoading = false
                    } else {
                        this.listLoading = false
                    }
                }).catch(error => {
                    this.listLoading = false
                    this.$notify({
                        title: '提示', message: '查询列表失败',
                        type: 'error', duration: 2000
                    })
                })
            },
            create(formName) {//添加数据
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        created(this.form).then(response => {
                            if(ResultMessage(response)) {
                                this.handleResetFilter()
                            } else {
                                this.dialogFormVisible = false
                            }
                        }).catch(error => {
                            this.$notify({
                                title: '提示', message: '添加失败',
                                type: 'error', duration: 2000
                            })
                        })
                    }
                })
            },
            update(formName) {//修改数据
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        updated(this.form).then(response => {
                            if(ResultMessage(response)) {
                                this.getPage()
                            }
                            this.dialogFormVisible = false
                        }).catch(error => {
                            this.$notify({
                                title: '提示', message: '修改失败',
                                type: 'error', duration: 2000
                            })
                        })
                    }
                })
            },
            cancel(formName) {
                this.dialogFormVisible = false
                const set = this.$refs
                set[formName].resetFields()
                this.form = {
                    sex: 1,
                    status: true
                }
            }
        }
    }
</script>

<style>
    .el-tree-node > .el-tree-node__children {
        overflow: visible;
    }
</style>

<!-- 局部样式 -->
<style rel="stylesheet/scss" lang="scss" scoped>
    .permissionDialog {
        width: 99.5%;
        height: 500px;
        overflow: auto;
        .custom-tree-node {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: space-between;
            font-size: 14px;
            padding-right: 8px;

            .node-label {
                width: 150px;
                min-width: 150px;
            }

            .node-permission {
                width: 100%;
                .el-checkbox-group{
                    font-size: 14px;
                }
            }
        }
    }

</style>